package com.youshang.nio;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.nio.Buffer;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;

/**
 * 使用FileInputStream 和 FileOutputStream
 * 获取到Channel
 * 将Channel中的数据写入/读取 到Buffer中
 * @author youshang
 * @date 2021/09/01 23:43
 **/
public class Test4 {

    public static void main(String[] args)  throws Exception{
        //1. 先拿到文件的输入流和输出流
        FileInputStream inputStream = new FileInputStream("input.txt");
        FileOutputStream outputStream = new FileOutputStream("output.txt");

        //2.从获取到的输入流和输出流 获取到各自的Channel
        FileChannel inputChannel = inputStream.getChannel();
        FileChannel outputChannel = outputStream.getChannel();
        //3. 创建一个ByteBuffer
        ByteBuffer buffer = ByteBuffer.allocate(512);
        //4. 声明一个死循环，直到文件读完为止
        while (true){
            // 5. 对Buffer进行一次清空(重置)
            buffer.clear();
            //6. 读取输入流中的内容 到Buffer
            int read = inputChannel.read(buffer);
            //7. 判断当前内容是否读取到末尾流(是否数据读完了)
            if (read == -1) {
                break;
            }
            // 8. 对buffer进行反转，从原先 用于读取文件的Buffer 转换为 用于写的buffer
            buffer.flip();
            // 9. 将buffer 写入到输出流中
            outputChannel.write(buffer);
        }

        test1();
    }

    // 第一个疑问：
    //为什么要调用buffer.clear() 方法？
    //第二个疑问：
    //为什么要调用buffer.flip() 就能达到切换 读写的功能？

    /**
     * 第一个疑问，第二个疑问 都需要关注下面三个关键参数
     * 需要关注 buffer的 position ， limit , capacity
     */
    public static void test1() throws Exception {
        FileInputStream inputStream = new FileInputStream("input.txt");
        FileOutputStream outputStream = new FileOutputStream("output.txt");

        FileChannel inputChannel = inputStream.getChannel();
        FileChannel outputChannel = outputStream.getChannel();

        // position = 0 , limit = 512 , capacity = 512
        ByteBuffer buffer = ByteBuffer.allocate(512);

        while (true) {
            // 第一次循环的时候： position = 0 , limit = 512 , capacity = 512
            // 第二次循环的时候： position = 0 , limit = 512 , capacity = 512
            //TODO 如果不调用clear， 会导致死循环，反复的写入 上一次的数据
            buffer.clear();

            // 第一次循环的时候： position = 11 , limit = 512 , capacity = 512
            // 第二次循环的时候： position = 0 , limit = 512 , capacity = 512
            int read = inputChannel.read(buffer);
            System.out.println("buffer.position() = " + buffer.position());
            System.out.println("buffer.limit() = " + buffer.limit());
            System.out.println("buffer.capacity() = " + buffer.capacity());

            System.out.println(read);//11

            // 第一次循环的时候,不满足直接跳过
            // 第二次循环的时候： read = -1 直接跳出
            if (read == -1) {
                break;
            }
            // 第一次循环的时候： position = 0 , limit = 11 , capacity = 512
            buffer.flip();

            // 第一次循环的时候： position = 11 , limit = 11 , capacity = 512
            outputChannel.write(buffer);
        }
    }

}
